﻿using Entities;
using Logger4Net;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Utilities;

namespace Hubberly
{
   public partial class TradeTicket : UserControl
   {
      public class FactoriesChangedEventArgs : EventArgs
      {
         public Material material;
         public int factoryCount;
         public int utilization;
      }
      public delegate void FactoriesChangedHandler(object sender, FactoriesChangedEventArgs eventArgs);
      public event FactoriesChangedHandler eventFactoriesChanged;

      public class SelectAllProducersEventArgs : EventArgs
      {
         public Material material;
      }
      public delegate void SelectAllProducersHandler(object sender, SelectAllProducersEventArgs eventArgs);
      public event SelectAllProducersHandler eventSelectAllProducers;

      //////////////////////////////////////////////////////////////////////////
      //
      public TradeTicket()
      {
         InitializeComponent();
         maskUtilization.delta = 10;
         maskUtilization.shiftDelta = 100;
         maskUtilization.maximum = 100;
         txtDailyDemand.ReadOnly = true;
         txtDailyDemand.TextAlign = HorizontalAlignment.Right;
         txtProduction.ReadOnly = true;
         txtProduction.TextAlign = HorizontalAlignment.Right;
         txtWarehouse.ReadOnly = true;
         txtWarehouse.TextAlign = HorizontalAlignment.Right;
         txtAdminBuy.ReadOnly = true;
         txtAdminBuy.TextAlign = HorizontalAlignment.Right;
         txtAdminSell.ReadOnly = true;
         txtAdminSell.TextAlign = HorizontalAlignment.Right;

         panelAdminSells.Dock = DockStyle.Fill;
         panelAdminBuys.Dock = DockStyle.Fill;
         panelDailyDemand.Dock = DockStyle.Fill;
         panelFactories.Dock = DockStyle.Fill;
         panelMaterial.Dock = DockStyle.Fill;
         panelProduction.Dock = DockStyle.Fill;
         panelUtilization.Dock = DockStyle.Fill;
         panelWarehouse.Dock = DockStyle.Fill;

         titleControls_ = new List<Control>(new Control[]
            {
               lblMaterial, lblFactories, lblAdminSell, lblAdminBuy, lblUtilization, lblWarehouse, lblDailyDemand, lblProduction
            });
         normalControls_ = new List<Control>(new Control[]
            {
               btnMaterial, maskFactories, txtAdminSell, txtAdminBuy, maskUtilization, txtWarehouse, txtDailyDemand, txtProduction
            });

         IEnumerator<Control> iterTitle = titleControls_.GetEnumerator();
         IEnumerator<Control> iterNormal = normalControls_.GetEnumerator();
         new string[] {
            "Material", "Factories", "Admin sells", "Admin buys", "Utilization", "Warehouse", "Change", "Net production"
            }.ToList().ForEach(title =>
            {
               iterTitle.MoveNext();
               iterNormal.MoveNext();
               Label controlTitle = iterTitle.Current as Label;
               Control controlNormal = iterNormal.Current;
               controlTitle.Text = title;
               controlTitle.Visible = false;
               controlNormal.Visible = true;
               controlTitle.Dock = controlNormal.Dock = DockStyle.Fill;
               controlTitle.TextAlign = ContentAlignment.MiddleCenter;
            });
      }

      //////////////////////////////////////////////////////////////////////////
      //
      public Material material
      {
         get { return material_; }
         set
         {
            material_ = value;
            btnMaterial.Text = material_.name;
         }
      }

      //////////////////////////////////////////////////////////////////////////
      //
      public City supplyHub
      {
         get { return supplyHub_; }
         set { supplyHub_ = value; }
      }

      //////////////////////////////////////////////////////////////////////////
      //
      public int factoriesActual
      {
         get { return (int)maskFactories.currentValue; }
         set { maskFactories.currentValue = value; }
      }

      //////////////////////////////////////////////////////////////////////////
      //
      public int factoriesNeeded
      {
         get { return factoriesNeeded_; }
         set
         {
            factoriesNeeded_ = value;
            string needText = Global.escapedString(factoriesNeeded_);
            maskFactories.maskBuilder = string.Concat("990 (", needText, ")");
         }
      }

      //////////////////////////////////////////////////////////////////////////
      //
      public string demandText
      {
         get { return txtDailyDemand.Text; }
         set { txtDailyDemand.Text = value; }
      }

      //////////////////////////////////////////////////////////////////////////
      //
      public bool factoriesEnabled
      {
         get { return maskFactories.Enabled; }
         set { maskFactories.Enabled = value; }
      }

      //////////////////////////////////////////////////////////////////////////
      //
      public string adminBuyText
      {
         get { return txtAdminBuy.Text; }
         set { txtAdminBuy.Text = value; }
      }

      //////////////////////////////////////////////////////////////////////////
      //
      public string adminSellText
      {
         get { return txtAdminSell.Text; }
         set { txtAdminSell.Text = value; }
      }

      //////////////////////////////////////////////////////////////////////////
      //
      public string warehouseText
      {
         get { return txtWarehouse.Text; }
         set { txtWarehouse.Text = value; }
      }

      //////////////////////////////////////////////////////////////////////////
      //
      public int utilization
      {
         get { return utilization_; }
         set
         {
            utilization_ = value;
            if (0 <= value)
            {
               maskUtilization.Enabled = true;
               maskUtilization.currentValue = utilization_;
               maskUtilization.maskBuilder = string.Concat("999");
            }
            else
            {
               maskUtilization.Enabled = false;
               maskUtilization.maskBuilder = string.Empty;
            }
         }
      }

      //////////////////////////////////////////////////////////////////////////
      //
      public string dailyProductionText
      {
         get { return txtProduction.Text; }
         set { txtProduction.Text = value; }
      }

      //////////////////////////////////////////////////////////////////////////
      //
      public List<double> columnWidths
      {
         get
         {
            List<double> result = new List<double>();
            try
            {
               result = layout.ColumnStyles.OfType<ColumnStyle>().Select<ColumnStyle, double>(style => style.Width).ToList();
            }
            catch (System.Exception ex)
            {
               logger_.exception(ex);
            }
            return result;
         }
      }

      //////////////////////////////////////////////////////////////////////////
      //
      public World world
      {
         set
         {
            try
            {
               world_ = value;
            }
            catch (System.Exception ex)
            {
               logger_.exception(ex);
            }
         }
      }

      //////////////////////////////////////////////////////////////////////////
      //
      private bool getValidNumber(MaskedTextBox box, out int theValue)
      {
         return int.TryParse(box.Text, System.Globalization.NumberStyles.AllowThousands,
            Global.cultureUSA_, out theValue);
      }

      //////////////////////////////////////////////////////////////////////////
      //
      private bool applyMaskBox(MaskedTextBox box)
      {
         bool result = false;
         try
         {
            if (box.Text != box.Tag as string)
            {
               int newValue;
               if (!getValidNumber(box, out newValue))
               {
                  return false;
               }
               logger_.errorFormat("Ignoring notification from unknown masked box type '{0}'", box.GetType().FullName);
               return false;
            }
         }
         catch (System.Exception ex)
         {
            logger_.exception(ex);
         }
         return result;
      }

      //////////////////////////////////////////////////////////////////////////
      //
      private void handleChanged(object sender, MaskUpDown.ChangedEventArgs eventArgs)
      {
         try
         {
            if ((maskFactories == sender as MaskUpDown) || (maskUtilization == sender as MaskUpDown))
            {
               if (null != eventFactoriesChanged)
               {
                  FactoriesChangedEventArgs rethrowArgs = new FactoriesChangedEventArgs();
                  rethrowArgs.material = material;
                  rethrowArgs.factoryCount = (int)maskFactories.currentValue;
                  rethrowArgs.utilization = (int)maskUtilization.currentValue;
                  eventFactoriesChanged(this, rethrowArgs);
               }
            }
         }
         catch (System.Exception ex)
         {
            logger_.exception(ex);
         }
      }

      //////////////////////////////////////////////////////////////////////////
      //
      private void btnMaterial_Click(object sender, EventArgs e)
      {
         try
         {
            if (null != eventSelectAllProducers)
            {
               SelectAllProducersEventArgs eventArgs = new SelectAllProducersEventArgs();
               eventArgs.material = material_;
               eventSelectAllProducers(sender, eventArgs);
            }
         }
         catch (System.Exception ex)
         {
            logger_.exception(ex);
         }
      }

      //////////////////////////////////////////////////////////////////////////
      //
      public bool titleBar
      {
         get { return titleBar_; }
         set
         {
            titleBar_ = value;

            titleControls_.ForEach(control => control.Visible = titleBar);
            normalControls_.ForEach(control => control.Visible = !titleBar);
         }
      }

      //////////////////////////////////////////////////////////////////////////
      //
      private Logger logger_ = new Logger(typeof(TradeTicket));
      private Material material_;
      private World world_;
      private City supplyHub_;
      private int factoriesNeeded_;
      private int utilization_;
      private bool titleBar_;
      List<Control> titleControls_, normalControls_;
   }
}
